Imports System.Collections.Generic
Imports System.Text

Namespace Core
	Friend NotInheritable Class DbtFile
		Inherits ClusteredFile
		Protected Shared mDbtHeaderWriter As QuickSerializer
		Protected Shared mDbtPageWriter As QuickSerializer
		Private mDbtHeader As DbtHeader
		Friend mDbfFile As DbfFile

		Public Sub New()
		End Sub

		Shared Sub New()
			'ignoremissingfields
			mDbtHeaderWriter = New QuickSerializer(GetType(DbtHeader), DbfVersion.DbfDotNet, Nothing, 0, False, True)
			'ignoremissingfields
			mDbtPageWriter = New QuickSerializer(GetType(DbtPage), DbfVersion.DbfDotNet, Nothing, 0, False, True)
		End Sub

		Protected Overrides Sub OnInitialize(stream As System.IO.Stream)
			Dim headerBuff As [Byte]() = New Byte(mDbtHeaderWriter.RecordWidth - 1) {}
			mDbtHeader = New DbtHeader()
			Dim read As Integer = stream.Read(headerBuff, 0, headerBuff.Length)

			If read > 0 Then
				mDbtHeaderWriter.Read(mDbfFile, headerBuff, mDbtHeader)
				mRecordWidth = mDbtHeader.BlockLength
				If mRecordWidth = 0 OrElse mDbtHeader.NdtVersion = 3 Then
					mRecordWidth = 512
				End If
				mHeaderWidth = mRecordWidth
			End If
		End Sub

        Protected Overrides Function OnCreateNewRecord(isNew As Boolean, recordNo As Int32) As Record
            Return New DbtPage()
        End Function

		Protected Overrides Sub OnWriteHeader(stream As System.IO.Stream)
			Throw New NotImplementedException()
		End Sub

		Protected Overrides Sub OnReadRecordBuffer(buffer As Byte(), record As Record)
            Dim dbtPage As Core.DbtPage = DirectCast(record, DbtPage)
			Dim result As System.IO.MemoryStream
			If mDbtHeader.NdtVersion = 3 Then
				result = New System.IO.MemoryStream()
				Dim seenTerminator As Boolean = False
				While seenTerminator = False
					For i As Integer = 0 To buffer.Length - 1
						If buffer(i) = &H1a Then
							If i > 0 Then
								result.Write(buffer, 0, i)
							End If
							seenTerminator = True
							Exit For
						End If
					Next
					If seenTerminator Then
						Exit While
					End If
					result.Write(buffer, 0, buffer.Length)

					If Not MyBase.ReadNextPage(buffer) Then
						System.Diagnostics.Debug.Assert(False, "We haven't seen the Terminator")
						Exit While
					End If
				End While
				dbtPage.Value = result.ToArray()
			Else
				mDbtPageWriter.Read(mDbfFile, buffer, dbtPage)
				result = New System.IO.MemoryStream()
				If dbtPage.Length <= buffer.Length - 8 Then
					result.Write(buffer, 8, CType(dbtPage.Length, Int32))
				Else
					result.Write(buffer, 8, buffer.Length - 8)
                    buffer = New [Byte](CInt(dbtPage.Length) - CInt(result.Length - 1)) {}
					MyBase.ReadNextPage(buffer)
				End If
			End If
			dbtPage.Value = result.ToArray()
		End Sub

		Friend Overrides Function OnFillWriteBuffer(record As Record, buffer As Byte()) As Boolean
			'throw new NotImplementedException();
			Return False
		End Function

        Protected Friend Overrides Function InternalGetRecord(recordNo As Int32, returnNullIfNotInCache As Boolean) As Record
            Return MyBase.InternalGetRecord(recordNo, returnNullIfNotInCache)
        End Function

		Public Overrides Sub Flush()
			MyBase.Flush()
		End Sub

		Public Overrides Function NewRecord() As Object
			Return MyBase.NewRecord()
		End Function

        Friend Overrides Sub OnWriteBufferModified(recordNo As Int32, oldBuffer As Byte(), newBuffer As Byte())
            MyBase.OnWriteBufferModified(recordNo, oldBuffer, newBuffer)
        End Sub

        Friend Function GetMemoValue(memoRecordNo As Int32) As Byte()
            'return null
            Dim page As DbtPage = DirectCast(InternalGetRecord(memoRecordNo - 1, False), DbtPage)
            Return page.Value
        End Function
	End Class
End Namespace
